package com.whfc.ms.config;

import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySources;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.whfc.common.entity.DefaultProperties;
import com.whfc.common.enums.SysRulePlatform;
import com.whfc.common.file.FilePathConfig;
import com.whfc.common.push.JpushProperties;
import com.whfc.common.spring.AppContextUtil;
import com.whfc.common.tencent.TrtcProperties;
import com.whfc.common.third.map.MapApi;
import com.whfc.common.third.map.impl.QQMapApi;
import com.whfc.common.third.map.impl.QQMapProperties;
import com.whfc.common.third.uni.UniProperties;
import com.whfc.entity.dto.msg.PushMsgDTO;
import com.whfc.fuum.dto.SysRuleDTO;
import com.whfc.fuum.service.SysUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2021-06-22 10:24
 */
@Configuration
@NacosPropertySources(value = {
        @NacosPropertySource(dataId = "com.whfc.ms.properties", autoRefreshed = true),
        @NacosPropertySource(dataId = "com.whfc.common.properties", autoRefreshed = true)
})
public class MsConfig {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${spring.profiles.active}")
    private String profile;

    @DubboReference(interfaceClass = SysUserService.class, version = "1.0.0")
    private SysUserService sysUserService;

    /**
     * 用户权限缓存(L1)
     *
     * @return
     */
    @Bean(name = "userRulesCache")
    public LoadingCache<Integer, Set<String>> userRulesCache() {
        LoadingCache<Integer, Set<String>> loadingCache = CacheBuilder.newBuilder()
                .initialCapacity(256)
                .maximumSize(1024)
                .expireAfterWrite(3, TimeUnit.MINUTES)
                .build(new CacheLoader<Integer, Set<String>>() {
                    @Override
                    public Set<String> load(Integer key) throws Exception {
                        //获取用户所有权限
                        List<SysRuleDTO> ruleDTOList = sysUserService.getUserRuleList(key, SysRulePlatform.MS.getValue());
                        //用户权限编码列表
                        Set<String> permissions = ruleDTOList.stream()
                                .map(SysRuleDTO::getCode)
                                .collect(Collectors.toSet());
                        logger.info("加载用户权限缓存,userId:{},rules:{}", key, permissions.size());
                        return permissions;
                    }
                });

        return loadingCache;
    }

    @Bean
    public RedisTemplate<String, PushMsgDTO> redisTemplate(RedisConnectionFactory connectionFactory) {
        Jackson2JsonRedisSerializer redisSerializer = new Jackson2JsonRedisSerializer(PushMsgDTO.class);
        RedisTemplate<String, PushMsgDTO> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(redisSerializer);
        return redisTemplate;
    }

    @Bean
    public FilePathConfig filePathConfig() {
        return new FilePathConfig("ms", profile);
    }

    @Bean
    public AppContextUtil getAppContextUtil() {
        return new AppContextUtil();
    }

    @Bean
    @ConfigurationProperties("whfc.default")
    public DefaultProperties defaultProperties() {
        return new DefaultProperties();
    }

    @Bean
    @ConfigurationProperties("third.trtc")
    public TrtcProperties trtcProperties() {
        return new TrtcProperties();
    }

    @Bean
    @ConfigurationProperties("third.jpush")
    public JpushProperties jpushProperties() {
        return new JpushProperties();
    }

    /**
     * 腾讯地图API-参数
     *
     * @return
     */
    @Bean(name = "qqMapProps")
    @ConfigurationProperties(prefix = "qqmap")
    public QQMapProperties qqMapProps() {
        return new QQMapProperties();
    }
    /**
     * 腾讯地图API
     *
     * @param qqMapProps
     * @return
     */
    @Bean(name = "qqMapApi")
    public MapApi qqMapApi(@Qualifier("qqMapProps") QQMapProperties qqMapProps) {
        return new QQMapApi(qqMapProps.getKey(), qqMapProps.getSk());
    }

    @Bean
    @ConfigurationProperties(prefix = "third.uni")
    public UniProperties uniProperties() {
        return new UniProperties();
    }
}
